using System.Globalization;
using CsvHelper;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PHMEE.EnergyEfficiency;
using Volo.Abp;

namespace PHMEE.ConsoleTools.EnergyEfficiency;

public class LogAbstractImporter
{
    public const string CommandName = "import-log-abstract";

    private ILogger<LogAbstractImporter> _logger;
    
    private LogAbstractAppService _logAbstractAppService;

    public async Task RunCommandAsync(string[] commandParts, IServiceProvider serviceProvider)
    {
        if (commandParts.Length != 3)
        {
            throw new UserFriendlyException("请提供船舶 Id 和 log abstract csv 文件路径");
        }

        var vesselId = commandParts[1];
        var filePath = commandParts[2];

        var vesselIdGuid = Guid.TryParse(vesselId, out var id)
            ? id
            : throw new UserFriendlyException("vesselId 不是有效的 Guid");
        if (string.IsNullOrWhiteSpace(filePath))
        {
            throw new UserFriendlyException("csv 文件路径不能为空");
        }

        _logger = serviceProvider.GetRequiredService<ILogger<LogAbstractImporter>>();
        _logAbstractAppService = serviceProvider.GetRequiredService<LogAbstractAppService>();

        await ImportAsync(vesselIdGuid, filePath);
    }

    private async Task ImportAsync(Guid vesselId, string filePath)
    {
        using var reader = new StreamReader(filePath);
        using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
        {
            var records = csv.GetRecords<LogAbstractDto>().ToList();

            foreach (var (record, index) in records.Select((record, index) => (record, index)))
            {
                try
                {
                    record.VoyageFrom = record.VoyageFrom.Trim();
                    record.VoyageTo = record.VoyageTo?.Trim();
                    
                    // var json = JsonSerializer.Serialize(record);
                    // Console.WriteLine(json);
                    
                    // 防止插入日志表时多线程争用 DbContext，所以在 foreach 中 await
                    await _logAbstractAppService.CreateAsync(vesselId, record);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "导入 log abstract 失败，行号：{0}", index);
                    break;
                }
            }
            
            _logger.LogInformation("导入 log abstract 完成");
            _logger.LogInformation("请按需删除 MySQL 中时序数据日志表的日志数据！！！！");
        }
    }
}